﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Net;

namespace NetOpen_System.Component
{
    /// <summary>
    /// IP匹配引擎
    /// </summary>
    public sealed class WebsiteFilter
    {
        
        private List<int> m_IPList = new List<int>();

        public WebsiteFilter(XmlNode node)
        {
            ParseFromNode(node);
        }

        private void ParseFromNode(XmlNode node)
        {
            if (node == null || !node.HasChildNodes)
                return;
            foreach (XmlNode n in node.ChildNodes)
            {
                if (n.Name == "add")
                    UpdateIPList(n, false);
                else if (n.Name == "remove")
                    UpdateIPList(n, true);
                else if (n.Name == "clear")
                    m_IPList.Clear();
            }
            m_IPList.Sort((int a, int b) => a - b);//升序排列
        }

        private void UpdateIPList(XmlNode node,bool isRemove)
        {
            XmlAttributeReader attReader = new XmlAttributeReader(node.Attributes);
            string ip1 = attReader.GetString("ip1", "");
            string ip2 = attReader.GetString("ip2", "");
            if (!IsValidIP(ip1))
                return;

            if (!IsValidIP(ip2))
            {
                //单IP处理
                AppendOrRemove(IPConvert(ip1), isRemove);
            }
            else if (ip1 == ip2)
            {
                //首尾一致的IP段
                AppendOrRemove(IPConvert(ip1), isRemove);                
            }
            else
            {
                //标准IP段处理
                int i1 = IPConvert(ip1);
                int i2 = IPConvert(ip2);
                int begin = Math.Min(i1, i2);
                int offset = Math.Abs(i2 - i1);

                for (int i = 0; i < offset + 1; i++)
                {
                    AppendOrRemove(begin + i, isRemove);
                }

            }            
        }

        private bool IsValidIP(string ip)
        {
            if (string.IsNullOrEmpty(ip))
                return false;
            IPAddress temp;
            return IPAddress.TryParse(ip, out temp);
        }

        private void AppendOrRemove(int ip, bool isRemove)
        {
            if (isRemove)
            {
                if (m_IPList.Contains(ip))
                    m_IPList.Remove(ip);
            }
            else
            {
                if (!m_IPList.Contains(ip))
                    m_IPList.Add(ip);
            }
        }

        private int IPConvert(string ip)
        {
            string[] strs = ip.Split('.');
            int result = 0;
            result = Convert.ToInt32(strs[0]) * 256 * 256 * 256 + Convert.ToInt32(strs[1]) * 256 * 256 + Convert.ToInt32(strs[2]) * 256 + Convert.ToInt32(strs[3]);
            return result;
        }

        /// <summary>
        /// 判断指定ip在当前列表中是否存在
        /// </summary>
        /// <param name="ip">指定的ip</param>
        /// <returns>存在true，不存在false</returns>
        public bool IsMatch(string ip)
        {
            if (m_IPList.Count == 0) return false;
            if (!IsValidIP(ip)) return false;
            int i = IPConvert(ip);

            if (i < m_IPList[0] || i > m_IPList[m_IPList.Count - 1])
                return false;

            return m_IPList.Contains(i);
        }
    }
}
